package org.android.application.marksixmanage.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.android.application.marksixmanage.model.BaseModelData;

import cn.bmob.BmobException;
import cn.bmob.BmobObject;
import cn.bmob.BmobQuery;
import cn.bmob.DeleteCallback;
import cn.bmob.FindCallback;
import cn.bmob.SaveCallback;

public abstract class BaseDao<T extends BaseModelData> {

	private String tableName;

	public String getTableName() {
		return tableName;
	}

	public BmobObject getBmobObject() {
		if (getTableName() != null) {
			return new BmobObject(getTableName());
		}
		return null;
	}

	public BmobQuery getBmobQuery() {
		if (getTableName() != null) {
			return new BmobQuery(getTableName());
		}
		return null;
	}

	public BaseDao(Class<T> clazz) {
		if (clazz != null) {
			this.tableName = clazz.getSimpleName();
		}
	}

	private BmobObject initBmobObject(Map<String, Object> paramMap) {
		BmobObject dataObject = getBmobObject();
		return initBmobObject(paramMap,dataObject);
	}
	
	private BmobObject initBmobObject(Map<String, Object> paramMap,BmobObject object){
		if (paramMap != null && !paramMap.isEmpty()) {
			for (String key : paramMap.keySet()) {
				object.put(key, paramMap.get(key));
			}
		}
		return object;
	}

	public void save(T data) throws BmobException {
		if (data != null) {
			Map<String, Object> paramMap = data.toMap();
			BmobObject dataObject =	initBmobObject(paramMap);
			dataObject.save();
		}
	}
	
	public void saveInBackground(T data) {
		if (data != null) {
			Map<String, Object> paramMap = data.toMap();
			BmobObject dataObject =	initBmobObject(paramMap);
			dataObject.saveInBackground();
		}
	}
	
	public void saveInBackground(T data,SaveCallback callback) {
		if (data != null) {
			Map<String, Object> paramMap = data.toMap();
			BmobObject dataObject =	initBmobObject(paramMap);
			dataObject.saveInBackground(callback);
		}
	}
	
	public void update(T data) throws BmobException{
		if(data!=null){
			if(data.getObjectId()==null){
				return;
			}
			BmobObject object = getBmobObject();
			BmobQuery query = getBmobQuery();
			object = query.get(data.getObjectId());
			object = initBmobObject(data.toMap(), object);
			object.save();
		}
	}
	
	public void updateInBackgound(T data,SaveCallback callback) throws BmobException{
		if(data!=null){
			if(data.getObjectId()==null){
				return;
			}
			BmobObject object = getBmobObject();
			BmobQuery query = getBmobQuery();
			object = query.get(data.getObjectId());
			object = initBmobObject(data.toMap(), object);
			if(callback==null)
				object.saveInBackground();
			else
				object.saveInBackground(callback);
		}
	}
	
	public void delete(T data) throws BmobException{
		if (data != null) {
			if(data.getObjectId()==null){
				return;
			}
			Map<String, Object> paramMap = data.toMap();
			BmobObject dataObject =	initBmobObject(paramMap);
			dataObject.delete();
		}
	}
	
	public void deleteInBackground(T data,DeleteCallback callback) throws BmobException{
		if (data != null) {
			if(data.getObjectId()==null){
				return;
			}
			Map<String, Object> paramMap = data.toMap();
			BmobObject dataObject =	initBmobObject(paramMap);
			
			if(callback!=null)
				dataObject.deleteInBackground(callback);
			else
				dataObject.deleteInBackground();
		}
	}
	
	public List<T> query(BmobQuery query) throws BmobException{
		List<BmobObject> oList = query.find();
		List<T> dataList = new ArrayList<T>();
		if(oList!=null){
			for(BmobObject object:oList){
				dataList.add(toData(object));
			}
		}
		return dataList;
	}
	
	public void queryInBackground(BmobQuery query,FindCallback callback) throws BmobException{
		query.findInBackground(callback);
	}
	
	public abstract T toData(BmobObject object);
}
